package com.warom.sdg.service;

import android.content.Context;
import android.util.Log;

import com.warom.sdg.database.SdgDatabase;
import com.warom.sdg.dto.AlarmHandleRequestDto;
import com.warom.sdg.dto.AlarmQueryRequestDto;
import com.warom.sdg.dto.AlarmRecordDto;
import com.warom.sdg.dto.AlarmStatisticsDto;
import com.warom.sdg.dto.PageRequestDto;
import com.warom.sdg.dto.PageResponseDto;
import com.warom.sdg.model.AlarmRecordEntity;
import com.warom.sdg.model.ApiResponse;
import com.warom.sdg.model.PlcDeviceEntity;
import com.warom.sdg.util.DateTimeUtil;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;

/**
 * 报警分析服务类
 * 处理报警分析相关的业务逻辑
 */
public class AlarmAnalysisService {
    private static final String TAG = "AlarmAnalysisService";
    private final SdgDatabase database;

    public AlarmAnalysisService(Context context) {
        this.database = SdgDatabase.getInstance(context);
    }

    /**
     * 查询报警记录
     * @param queryRequest 查询请求
     * @return 查询结果
     */
    public ApiResponse<PageResponseDto<AlarmRecordDto>> queryAlarms(AlarmQueryRequestDto queryRequest) {
        try {
            // 处理查询参数
            String alarmType = queryRequest.getAlarmType();
            String paramType = queryRequest.getParamType();
            String level = queryRequest.getLevel();
            String status = queryRequest.getStatus();
            String timeRange = queryRequest.getTimeRange();

            // 转换报警级别
            if (level != null && !"all".equals(level)) {
                level = level.toUpperCase();
            }

            // 计算时间范围
            long startTime = queryRequest.getStartTime();
            long endTime = queryRequest.getEndTime();

            if (startTime <= 0 || endTime <= 0) {
                switch (timeRange) {
                    case "today":
                        startTime = DateTimeUtil.getStartOfDay();
                        endTime = System.currentTimeMillis();
                        break;
                    case "week":
                        startTime = DateTimeUtil.getStartOfDay() - 6 * 24 * 60 * 60 * 1000L;
                        endTime = System.currentTimeMillis();
                        break;
                    case "month":
                        startTime = DateTimeUtil.getStartOfDay() - 29 * 24 * 60 * 60 * 1000L;
                        endTime = System.currentTimeMillis();
                        break;
                    default:
                        startTime = 0;
                        endTime = System.currentTimeMillis();
                }
            }

            // 查询数据库
            PageRequestDto pageRequest = new PageRequestDto(queryRequest.getPage(), queryRequest.getPageSize());
            PageResponseDto<AlarmRecordEntity> entityResponse = database.getAlarmRecordDao()
                    .queryAlarmRecords(
                            "all".equals(alarmType) ? null : alarmType,
                            "all".equals(paramType) ? null : paramType,
                            "all".equals(level) ? null : level,
                            "all".equals(status) ? null : status,
                            startTime,
                            endTime,
                            pageRequest
                    );

            // 转换为DTO
            List<AlarmRecordDto> dtoList = convertToDto(entityResponse.getList());

            // 构建响应
            PageResponseDto<AlarmRecordDto> response = new PageResponseDto<AlarmRecordDto>(
                    entityResponse.getPage(),
                    entityResponse.getPageSize(),
                    entityResponse.getTotalCount(),
                    dtoList
            );

            return new ApiResponse<>(true, "查询报警记录成功", response);

        } catch (Exception e) {
            Log.e(TAG, "查询报警记录失败: " + e.getMessage());
            return new ApiResponse<>(false, "查询报警记录失败: " + e.getMessage(), null);
        }
    }

    /**
     * 处理报警
     * @param handleRequest 处理请求
     * @return 处理结果
     */
    public ApiResponse<Boolean> handleAlarm(AlarmHandleRequestDto handleRequest) {
        try {
            // 获取报警记录
            AlarmRecordEntity alarm = database.getAlarmRecordDao().getAlarmRecordById(handleRequest.getId());

            if (alarm == null) {
                return new ApiResponse<>(false, "未找到指定报警记录", false);
            }

            // 设置状态
            String status = "HANDLE".equals(handleRequest.getAction()) ? "HANDLED" : "IGNORED";

            // 更新数据库
            int result = database.getAlarmRecordDao()
                    .updateAlarmStatus(
                            handleRequest.getId(),
                            status,
                            handleRequest.getHandleUser(),
                            handleRequest.getHandleDescription()
                    );

            // 构建响应
            boolean success = result > 0;
            String message = success ? "处理报警成功" : "处理报警失败";

            return new ApiResponse<>(success, message, success);

        } catch (Exception e) {
            Log.e(TAG, "处理报警失败: " + e.getMessage());
            return new ApiResponse<>(false, "处理报警失败: " + e.getMessage(), false);
        }
    }

    /**
     * 获取报警详情
     * @param id 报警ID
     * @return 报警详情
     */
    public ApiResponse<AlarmRecordDto> getAlarmDetail(long id) {
        try {
            // 查询数据库
            AlarmRecordEntity alarm = database.getAlarmRecordDao().getAlarmRecordById(id);

            if (alarm == null) {
                return new ApiResponse<>(false, "未找到指定报警记录", null);
            }

            // 转换为DTO
            AlarmRecordDto dto = convertToDto(alarm);

            return new ApiResponse<>(true, "获取报警详情成功", dto);

        } catch (Exception e) {
            Log.e(TAG, "获取报警详情失败: " + e.getMessage());
            return new ApiResponse<>(false, "获取报警详情失败: " + e.getMessage(), null);
        }
    }

    /**
     * 获取报警统计数据
     * @param alarmType 报警类型
     * @param timeRange 时间范围
     * @param startTime 开始时间
     * @param endTime 结束时间
     * @return 统计数据
     */
    public ApiResponse<AlarmStatisticsDto> getAlarmStatistics(String alarmType, String timeRange,
                                                            long startTime, long endTime) {
        try {
            // 计算时间范围
            if (startTime <= 0 || endTime <= 0) {
                switch (timeRange) {
                    case "today":
                        startTime = DateTimeUtil.getStartOfDay();
                        endTime = System.currentTimeMillis();
                        break;
                    case "week":
                        startTime = DateTimeUtil.getStartOfDay() - 6 * 24 * 60 * 60 * 1000L;
                        endTime = System.currentTimeMillis();
                        break;
                    case "month":
                        startTime = DateTimeUtil.getStartOfDay() - 29 * 24 * 60 * 60 * 1000L;
                        endTime = System.currentTimeMillis();
                        break;
                    default:
                        startTime = 0;
                        endTime = System.currentTimeMillis();
                }
            }

            // 查询数据库
            int[] levelCounts = database.getAlarmRecordDao()
                    .countAlarmsByLevel("all".equals(alarmType) ? null : alarmType, startTime, endTime);

            int[] statusCounts = database.getAlarmRecordDao()
                    .countAlarmsByStatus("all".equals(alarmType) ? null : alarmType, startTime, endTime);

            // 构建统计数据
            AlarmStatisticsDto statistics = new AlarmStatisticsDto();

            // 设置级别数据
            statistics.addLevelData("high", levelCounts[0]);
            statistics.addLevelData("medium", levelCounts[1]);
            statistics.addLevelData("low", levelCounts[2]);

            // 设置状态数据
            statistics.addStatusData("active", statusCounts[0]);
            statistics.addStatusData("handled", statusCounts[1]);
            statistics.addStatusData("ignored", statusCounts[2]);

            // 设置总数
            statistics.setTotalCount(levelCounts[0] + levelCounts[1] + levelCounts[2]);

            return new ApiResponse<>(true, "获取报警统计数据成功", statistics);

        } catch (Exception e) {
            Log.e(TAG, "获取报警统计数据失败: " + e.getMessage());
            return new ApiResponse<>(false, "获取报警统计数据失败: " + e.getMessage(), null);
        }
    }

    /**
     * 创建报警记录
     * @param dto 报警记录DTO
     * @return 创建结果
     */
    public ApiResponse<Long> createAlarmRecord(AlarmRecordDto dto) {
        try {
            // 转换为实体
            AlarmRecordEntity entity = convertToEntity(dto);

            // 设置创建时间
            if (entity.getCreateTime() <= 0) {
                entity.setCreateTime(System.currentTimeMillis());

                // 格式化时间
                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault());
                entity.setCreateTimeString(sdf.format(new Date(entity.getCreateTime())));
            }

            // 设置状态
            if (entity.getStatus() == null || entity.getStatus().isEmpty()) {
                entity.setStatus("ACTIVE");
            }

            // 插入数据库
            long id = database.getAlarmRecordDao().insertAlarmRecord(entity);

            if (id > 0) {
                return new ApiResponse<>(true, "创建报警记录成功", id);
            } else {
                return new ApiResponse<>(false, "创建报警记录失败", -1L);
            }

        } catch (Exception e) {
            Log.e(TAG, "创建报警记录失败: " + e.getMessage());
            return new ApiResponse<>(false, "创建报警记录失败: " + e.getMessage(), -1L);
        }
    }

    /**
     * 将实体转换为DTO
     * @param entity 实体
     * @return DTO
     */
    private AlarmRecordDto convertToDto(AlarmRecordEntity entity) {
        if (entity == null) {
            return null;
        }

        AlarmRecordDto dto = new AlarmRecordDto();
        dto.setId(entity.getId());
        dto.setAlarmType(entity.getAlarmType());
        dto.setParamType(entity.getParamType());
        dto.setDeviceId(entity.getDeviceId());
        dto.setLocation(entity.getLocation());
        dto.setValue(entity.getValue());
        dto.setUnit(entity.getUnit());
        dto.setThresholdMin(entity.getThresholdMin());
        dto.setThresholdMax(entity.getThresholdMax());
        dto.setLevel(entity.getLevel());
        dto.setStatus(entity.getStatus());
        dto.setDescription(entity.getDescription());
        dto.setCreateTime(entity.getCreateTime());
        dto.setCreateTimeString(entity.getCreateTimeString());
        dto.setHandleTime(entity.getHandleTime());
        dto.setHandleUser(entity.getHandleUser());
        dto.setHandleDescription(entity.getHandleDescription());

        // 如果有处理时间，格式化处理时间
        if (entity.getHandleTime() > 0) {
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault());
            dto.setHandleTimeString(sdf.format(new Date(entity.getHandleTime())));
        }

        // 获取设备名称
        if (entity.getDeviceId() > 0) {
            try {
                PlcDeviceEntity device = database.getPlcDeviceDao().getDeviceById((int) entity.getDeviceId());
                if (device != null) {
                    dto.setDeviceName(device.getDeviceName());
                }
            } catch (Exception e) {
                Log.e(TAG, "获取设备信息失败: " + e.getMessage());
            }
        }

        return dto;
    }

    /**
     * 将实体列表转换为DTO列表
     * @param entities 实体列表
     * @return DTO列表
     */
    private List<AlarmRecordDto> convertToDto(List<AlarmRecordEntity> entities) {
        if (entities == null) {
            return new ArrayList<>();
        }

        List<AlarmRecordDto> dtoList = new ArrayList<>();

        for (AlarmRecordEntity entity : entities) {
            dtoList.add(convertToDto(entity));
        }

        return dtoList;
    }

    /**
     * 将DTO转换为实体
     * @param dto DTO
     * @return 实体
     */
    private AlarmRecordEntity convertToEntity(AlarmRecordDto dto) {
        if (dto == null) {
            return null;
        }

        AlarmRecordEntity entity = new AlarmRecordEntity();
        entity.setId(dto.getId());
        entity.setAlarmType(dto.getAlarmType());
        entity.setParamType(dto.getParamType());
        entity.setDeviceId(dto.getDeviceId());
        entity.setLocation(dto.getLocation());
        entity.setValue(dto.getValue());
        entity.setUnit(dto.getUnit());
        entity.setThresholdMin(dto.getThresholdMin());
        entity.setThresholdMax(dto.getThresholdMax());
        entity.setLevel(dto.getLevel());
        entity.setStatus(dto.getStatus());
        entity.setDescription(dto.getDescription());
        entity.setCreateTime(dto.getCreateTime());
        entity.setCreateTimeString(dto.getCreateTimeString());
        entity.setHandleTime(dto.getHandleTime());
        entity.setHandleUser(dto.getHandleUser());
        entity.setHandleDescription(dto.getHandleDescription());

        return entity;
    }
} 